/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = ibmmq_analysis.c                                              */
/*  NOTE      = IBM MQ协议解析                                                */
/*  DATE      = 2015/06/03 by wuwk                                            */
/******************************************************************************/
//#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <libxml/xpath.h>
#include <libxml/parser.h>
#include <unistd.h>
//#undef _GNU_SOURCE

#if defined(FRLINUX4) || defined(FRLINUX5)
    #include "endian_dbg.h"
#else
    #include <endian.h>
#endif

#include "frcomm.h"
#include "frsoap_parse.h"
#include "ibmmq_core.h"
#include "ibmmq_analysis.h"
#include "ibmmq_charset.h"
#include "ibmmq_comm.h"

#define IBMMQ_PMO_V1_LEN                     128
#define IBMMQ_PMO_V2_LEN                     152
#define IBMMQ_GMO_V1_LEN                     72
#define IBMMQ_GMO_V2_LEN                     80
#define IBMMQ_GMO_V3_LEN                     100
#define IBMMQ_MD_V1_LEN                      324
#define IBMMQ_MD_V2_LEN                      364

#define IBMMQ_MQMD_STRUCTID             "MD"
#define IBMMQ_OD_STRUCTID               "OD"
#define IBMMQ_STRUCTID_XQH              "XQH "
#define IBMMQ_STRUCTID_DLH              "DLH "
#define IBMMQ_STRUCTID_MDE              "MDE "
#define IBMMQ_STRUCTID_CIH              "CIH "
#define IBMMQ_STRUCTID_IIH              "IIH "
#define IBMMQ_STRUCTID_RFH              "RFH "
#define IBMMQ_STRUCTID_RMH              "RMH"
#define IBMMQ_STRUCTID_WIH              "WIH"
#define IBMMQ_STRUCTID_MSH              "MSH"

#define IBMMQ_UNKNOWN_CHANNEL    "UNKNOWN_CHANNEL"

#define IBMMQ_JMS_TEXT                  "jms_text"
#define IBMMQ_JMS_MAP                   "jms_map"
#define IBMMQ_JMS_OBJ                   "jms_object"
#define IBMMQ_JMS_STREAM                "jms_stream"
#define IBMMQ_JMS_BYTE                  "jms_bytes"
#define IBMMQ_MSG_TYPE_TEXT             "text"
#define IBMMQ_MSG_TYPE_MAP              "hashmap"
#define IBMMQ_MSG_TYPE_OBJ              "binary"
#define IBMMQ_MSG_TYPE_LIST             "list"

#define IBMMQ_MAP_DATA_TYPE_CHAR      "char"
#define IBMMQ_MAP_DATA_TYPE_BYTE      "i1"
#define IBMMQ_MAP_DATA_TYPE_SHORT     "i2"
#define IBMMQ_MAP_DATA_TYPE_INT       "i4"
#define IBMMQ_MAP_DATA_TYPE_LONG      "i8"
#define IBMMQ_MAP_DATA_TYPE_FLOAT     "r4"
#define IBMMQ_MAP_DATA_TYPE_DOUBLE    "r8"

#define IBMMQ_SPI_TYPE_QUERY            1
#define IBMMQ_SPI_TYPE_OPEN             12
#define IBMMQ_SPI_TYPE_UNKNOWN          7

#define MQ_METHOD             "request.mq.method"

#define MQ_SUB                          APM_REPORT_KEY_SUB".mq"
#define MQ_SUB_QUE                      MQ_SUB".queue"

#define MQ_NOTIFY                       APM_REPORT_KEY_NOTIFY".mq"
#define MQ_NOTIFY_TOPIC                   MQ_NOTIFY".topic"

#define MQ_REQ_QUE                 APM_REPORT_KEY_REQ".mq.queue"

#define MQ_REPORT_MQ                 "mq"
#define MQ_REPORT_MQ_MSG             "mq.message"
#define MQ_REPORT_MQ_MSG_TEXT             "mq.message.text"
#define MQ_REPORT_MQ_MSG_MAP             "mq.message.map"
#define MQ_REPORT_MQ_MSG_OBJ             "mq.message.binary"

#define MQ_REPOER_MQ_MSG_TYPE            "mq.message.type"

#define MQ_PRIORITY_REQ                       "request.mq.priority"
#define MQ_PRIORITY_RESP                       "response.mq.priority"
#define MQ_PRIORITY_NOTIFY                       "notify.mq.priority"

#define IBMMQ_RESP_CODE           "response.code"
#define IBMMQ_RESP_CODE_STRING         "response.code_string"

#define MQ_MESSAGE_SIZE          "mq.message.size"

extern void *g_p_apm_context;

/*******************************************************************************
*  FUNC     :  根据字节数取得数据（p_st_data指针不移动）
*  ARGS     :  p_st_data(数据)
            :  ui_bytes(要取得数据的长度)
            :  pp_out(取得的数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_get_data_by_bytes(Frbyte_Packet *p_st_data
                                      , unsigned int ui_bytes
                                      , char **pp_out)
{
    char *p_out = NULL;
    int i_ret = 0;

    if (p_st_data == NULL || pp_out == NULL || ui_bytes == 0)
        return FR_FAIL;

    p_out = (char *)frmalloc(ui_bytes + 1);
    if (p_out == NULL)
        return FR_FAIL;
    memset(p_out, 0x00, ui_bytes + 1);

    i_ret = bytebuff_peek_bytes(p_st_data, p_out, ui_bytes);
    if (i_ret != FR_SUCC)
    {
        frfree(p_out);
        return FR_FAIL;
    }

    *pp_out = p_out;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQMD解析
*  ARGS     :  p_st_body_data(上报链表)
            :  u32_byte_order(数据读取方式)
            :  p_st_data(数据)
            :  p_ui_data_len(数据长度)
            :  p_s_ccsid(CCSID)
            :  p_format(数据格式)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_md_analysis(L7session_ibmmq_private *p_st_private
                                , Frreport_body_data *p_st_body_data
                                , uint32_t u32_byte_order
                                , Frbyte_Packet *p_st_data
                                , unsigned int *p_ui_data_len
                                , short *p_s_ccsid
                                , int i_req_resp
                                , char *p_format)
{
    char arr_priority[64];
    unsigned int ui_left_len = 0;
    int i_ret = 0;
    int i_size = 0;
    int i_offset = 0;
    int i_version = 0;
    uint32_t u32_value = 0;
    uint32_t u32_priority = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    ui_left_len = *p_ui_data_len;

    if (ui_left_len < 8)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, 4);
    i_offset += 4;

    /* Version */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    i_offset += 4;

    i_version = u32_value;
    /* 判断版本号 */
    switch (i_version)
    {
        case 1: i_size = IBMMQ_MD_V1_LEN;break;
        case 2: i_size = IBMMQ_MD_V2_LEN;break;
    }

    if ((int)ui_left_len < i_size - 8)
        return APM_L7_ANALYZE_TODO;

    /* 定位到CCSID位置 */
    bytebuff_skip(p_st_data, 20);
    i_offset += 20;

    /* CCSID */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    *p_s_ccsid = u32_value;

    i_offset += 4;

    /* 取消息类型(Format) */
    i_ret = bytebuff_get_bytes(p_st_data, p_format, 8);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    i_offset += 8;

    /* 消息优先级 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_priority, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    i_offset += 4;

    /* PutAppTyp */
    bytebuff_skip(p_st_data, 228);
    i_offset += 228;
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    i_offset += 4;

    /* PUBLISH/BROKER */
    if (u32_value == 26)
        p_st_private->i_pubsub_flag = IBMMQ_MSG_NOTIFY;

    /* 消息优先级为0-9 */
    if (u32_priority >= 0 && u32_priority <= 9)
    {
        if (i_req_resp == IBMMQ_REQUEST)
            i_ret = frreport_body_l7_add_int(p_st_body_data, MQ_PRIORITY_REQ, u32_priority);
        else if (p_st_private->i_pubsub_flag == IBMMQ_MSG_NOTIFY)
        {
            snprintf(arr_priority, sizeof(arr_priority), "%s.1", MQ_PRIORITY_NOTIFY);
            i_ret = frreport_body_l7_add_int(p_st_body_data, arr_priority, u32_priority);
        }
        else
        {
            snprintf(arr_priority, sizeof(arr_priority), "%s.1", MQ_PRIORITY_RESP);
            i_ret = frreport_body_l7_add_int(p_st_body_data, arr_priority, u32_priority);
        }
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    /* 到MD结束位置 */
    bytebuff_skip(p_st_data, i_size - i_offset);
    ui_left_len -= i_size;

    *p_ui_data_len = ui_left_len;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  PMO长度跳过
*  ARGS     :  p_st_data(数据)
            :  p_ui_data_len(数据长度)
            :  u32_byte_order(数据读取方式)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_pmo_analysis(Frbyte_Packet *p_st_data
                                 , unsigned int *p_ui_data_len
                                 , uint32_t u32_byte_order)
{
    unsigned int ui_left_len = 0;
    int i_size = 0;
    int i_ret = 0;
    uint32_t u32_version = 0;

    if (p_st_data == NULL || p_ui_data_len == NULL)
        return FR_FAIL;

    ui_left_len = *p_ui_data_len;

    if (ui_left_len < 8)
        return FR_FAIL;

    /* StructID */
    bytebuff_skip(p_st_data, 4);
    ui_left_len -= 4;

    /* 取得Version */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_version, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_left_len -= 4;

    /* 判断版本号 */
    switch (u32_version)
    {
        case 1: i_size = IBMMQ_PMO_V1_LEN;break;
        case 2: i_size = IBMMQ_PMO_V2_LEN;break;
    }

    if ((int)ui_left_len < i_size - 8)
        return FR_FAIL;

    bytebuff_skip(p_st_data, i_size - 8);
    ui_left_len -= (i_size - 8);

    *p_ui_data_len = ui_left_len;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  JMS数据里取队列名
*  ARGS     :  p_st_l7_session(session数据)
            :  p_st_data(数据)
            :  ui_jms_len(数据长度)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_jms_get_queue(L7Session_ibmmq *p_st_l7_session
                                  , Frbyte_Packet *p_st_data
                                  , unsigned int ui_jms_len)
{
    xmlDocPtr p_st_doc = NULL;
    xmlNodePtr p_st_root = NULL;
    xmlNodePtr p_st_current = NULL;
    xmlChar *p_content = NULL;
    xmlChar *p_queue = NULL;
    char *p_data = NULL;
    int i_ret = 0;

    if (p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_data = (char *)frmalloc(ui_jms_len + 1);
    if (p_data == NULL)
        return FR_FAIL;
    memset(p_data, 0x00, ui_jms_len + 1);

    /* 取JMS数据 */
    i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_jms_len);
    if (i_ret == FR_FAIL)
        goto err;

    p_st_doc = xmlReadMemory(p_data, ui_jms_len, NULL, NULL, XML_PARSE_NOBLANKS|XML_PARSE_NOERROR|XML_PARSE_NOWARNING);
    if (p_st_doc == NULL)
        goto err;

    /* 根节点 */
    p_st_root = xmlDocGetRootElement(p_st_doc);
    if (p_st_root == NULL)
        goto err;

    p_st_current = xmlFirstElementChild(p_st_root);
    if (p_st_current == NULL)
        goto err;

    if (xmlStrcmp(p_st_current->name, (const xmlChar *) "Dst"))
    {
        frfree(p_data);
        xmlFreeDoc(p_st_doc);
        return FR_SUCC;
    }

    /* 队列名 */
    p_content = xmlNodeGetContent(p_st_current);
    if (p_content == NULL)
        goto err;

    p_queue = (xmlChar *)xmlStrstr(p_content, (xmlChar *)":///");
    if (p_queue == NULL)
        goto err;

    p_queue += 4;
    if (p_st_l7_session->p_queue == NULL)
    {
        p_st_l7_session->p_queue = frstrdup((char *)p_queue);
        if (p_st_l7_session->p_queue == NULL)
            goto err;
    }
    else if (strncmp(p_st_l7_session->p_queue, (char *)p_queue, strlen(p_st_l7_session->p_queue)) != 0)
    {
        frfree(p_st_l7_session->p_queue);
        p_st_l7_session->p_queue = frstrdup((char *)p_queue);
        if (p_st_l7_session->p_queue == NULL)
            goto err;
    }

    frfree(p_data);
    xmlFreeDoc(p_st_doc);
    xmlFree(p_content);

    return FR_SUCC;

err:
    frfree(p_data);
    xmlFreeDoc(p_st_doc);
    if (p_content)
        xmlFree(p_content);

    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  JMS数据解析
*  ARGS     :  p_st_private(IBM MQ私有数据)
            :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  ui_jms_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_jms_data_analysis(L7session_ibmmq_private *p_st_private
                                      , Frreport_body_data *p_st_body_data
                                      , Frbyte_Packet *p_st_data
                                      , unsigned int ui_jms_len
                                      , char *p_report_pre)
{
    xmlDocPtr p_st_doc = NULL;
    xmlNodePtr p_st_root = NULL;
    xmlNodePtr p_st_current = NULL;
    xmlChar *p_content = NULL;
    char *p_jms_data = NULL;
    char arr_key[64];
    uint32_t u32_jms_len = 0;
    unsigned int ui_left_len = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_body_data == NULL || p_st_data == NULL
        || p_report_pre == NULL)
        return FR_FAIL;

    p_jms_data = (char *)frmalloc(ui_jms_len + 1);
    if (p_jms_data == NULL)
        return FR_FAIL;
    memset(p_jms_data, 0x00, ui_jms_len + 1);

    /* 取JMS数据 */
    i_ret = bytebuff_peek_bytes(p_st_data, p_jms_data, ui_jms_len);
    if (i_ret == FR_FAIL)
        goto err;

    p_st_doc = xmlReadMemory(p_jms_data, ui_jms_len, NULL, NULL, XML_PARSE_NOBLANKS|XML_PARSE_NOERROR|XML_PARSE_NOWARNING);
    if (p_st_doc == NULL)
        goto err;

    /* 根节点 */
    p_st_root = xmlDocGetRootElement(p_st_doc);
    if (p_st_root == NULL)
        goto err;

    p_st_current = xmlFirstElementChild(p_st_root);
    if (p_st_current == NULL)
        goto err;

    if (xmlStrcmp(p_st_current->name, (const xmlChar *) "Msd"))
    {
        bytebuff_skip(p_st_data, ui_jms_len);
        frfree(p_jms_data);
        xmlFreeDoc(p_st_doc);
        return FR_SUCC;
    }

    /* 数据类型 */
    p_content = xmlNodeGetContent(p_st_current);
    if (p_content == NULL)
        goto err;

    snprintf(arr_key, sizeof(arr_key), "%s%s.1", p_report_pre, MQ_REPOER_MQ_MSG_TYPE);

    if (xmlStrcmp(p_content, (const xmlChar *)IBMMQ_JMS_TEXT) == 0)
    {
        /* message.type上报 */
        if (frreport_body_l7_add_str(p_st_body_data, arr_key, IBMMQ_MSG_TYPE_TEXT) == FR_FAIL)
            goto err;
        p_st_private->i_msg_type = IBMMQ_MSG_TYPE_TEXT_FLG;
    }
    else if (xmlStrcmp(p_content, (const xmlChar *) IBMMQ_JMS_MAP) == 0)
    {
        /* message.type上报 */
        if (frreport_body_l7_add_str(p_st_body_data, arr_key, IBMMQ_MSG_TYPE_MAP) == FR_FAIL)
            goto err;
        p_st_private->i_msg_type = IBMMQ_MSG_TYPE_MAP_FLG;
    }
    else if (xmlStrcmp(p_content, (const xmlChar *) IBMMQ_JMS_OBJ) == 0
        || xmlStrcmp(p_content, (const xmlChar *) IBMMQ_JMS_STREAM) == 0
        || xmlStrcmp(p_content, (const xmlChar *) IBMMQ_JMS_BYTE) == 0)
    {
        /* message.type上报 */
        if (frreport_body_l7_add_str(p_st_body_data, arr_key, IBMMQ_MSG_TYPE_OBJ) == FR_FAIL)
            goto err;
        p_st_private->i_msg_type = IBMMQ_MSG_TYPE_OBJ_FLG;
    }
    else
        goto err;

    /* 32为固定长度 */
    bytebuff_skip(p_st_data, 32);
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_jms_len, (LITTLE_BIG_ENDIAN)BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        goto err;

    i_ret = __ibmmq_jms_get_queue(p_st_private->p_st_l7_session, p_st_data, u32_jms_len);
    if (i_ret == FR_FAIL)
        goto err;

    ui_left_len = ui_jms_len - 32 - 4 - u32_jms_len;
    if ( ui_left_len> 0)
        bytebuff_skip(p_st_data, ui_left_len);

    frfree(p_jms_data);
    xmlFreeDoc(p_st_doc);
    xmlFree(p_content);

    return FR_SUCC;

err:
    frfree(p_jms_data);
    xmlFreeDoc(p_st_doc);
    if (p_content)
        xmlFree(p_content);

    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  数据部分头解析
*  ARGS     :  p_st_private(IBM MQ私有数据)
            :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  ui_left_len(数据长度)
            :  p_report_pre(上报前缀)
            :  p_ui_offset(offset)
            :  p_s_ccsid(CCSID)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_submd_analysis(L7session_ibmmq_private *p_st_private
                                   , Frreport_body_data *p_st_body_data
                                   , Frbyte_Packet *p_st_data
                                   , unsigned int ui_left_len
                                   , char *p_report_pre
                                   , unsigned int *p_ui_offset
                                   , short *p_s_ccsid)
{
    int i_ret = 0;
    int i_size = 0;
    unsigned int ui_len = 0;
    unsigned int ui_offset = 0;
    unsigned int ui_head_len = 0;
    unsigned int ui_jms_len = 0;
    uint32_t u32_value = 0;
    short s_ccsid = *p_s_ccsid;
    char *p_data = NULL;
    char *p_out = NULL;
    L7_head_ibmmq *p_st_head = NULL;
    uint32_t u32_byte_order = 1;

    if (p_st_body_data == NULL || p_st_data == NULL
        || p_ui_offset == NULL || p_s_ccsid == NULL)
        return FR_FAIL;

    if (ui_left_len < 4)
        return APM_L7_ANALYZE_TODO;

    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    /* 取StructID */
    i_ret = __ibmmq_get_data_by_bytes(p_st_data, 4, &p_data);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* StructID 为 XQH */
    if (strncmp(p_data, IBMMQ_STRUCTID_XQH, 4) == 0)
    {
        /* XQH长度104 */
        i_size = 104;
        if ((int)ui_left_len < i_size)
        {
            frfree(p_data);
            return APM_L7_ANALYZE_TODO;
        }

        bytebuff_skip(p_st_data, i_size);
        ui_left_len -= i_size;
        ui_offset += i_size;

        /* 取头部 */
        i_ret = __ibmmq_get_data_by_bytes(p_st_data, IBMMQ_HEAD_LEN_TSHM, &p_out);
        if (i_ret == FR_FAIL)
            goto err;

        if (strncmp(p_out, IBMMQ_STR_TSHM, IBMMQ_TSHx_LEN) == 0)
        {
            ui_head_len = IBMMQ_HEAD_LEN_TSHM;
        }
        else
        {
            ui_head_len = IBMMQ_HEAD_LEN_TSH;
            p_out[IBMMQ_HEAD_LEN_TSH] = '\0';
        }
        frfree(p_out);
        if (ui_left_len < ui_head_len)
        {
            frfree(p_data);
            return APM_L7_ANALYZE_TODO;
        }

        bytebuff_skip(p_st_data, ui_head_len);
        ui_left_len -= ui_head_len;
        ui_offset += ui_head_len;

        frfree(p_data);
        if (ui_left_len < 4)
        {
            *p_ui_offset = ui_offset;
            *p_s_ccsid = p_st_head->s_ccsid;
            return FR_SUCC;
        }

        /* 取StructID */
        i_ret = __ibmmq_get_data_by_bytes(p_st_data, 4, &p_data);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        s_ccsid = p_st_head->s_ccsid;
    }

    /* notify时用数据包定义的读取方式，其他用大头 */
    if (p_st_private->i_pubsub_flag == IBMMQ_MSG_NOTIFY)
        u32_byte_order = p_st_head->u32_byte_order;

    if (strncmp(p_data, IBMMQ_STRUCTID_DLH, 4) == 0)
    {
        i_size = 172;

        if ((int)ui_left_len < i_size)
        {
            frfree(p_data);
            return APM_L7_ANALYZE_TODO;
        }

        /* Encoding */
        bytebuff_skip(p_st_data, 108);

        /* CCSID */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)u32_byte_order);
        if (i_ret == FR_FAIL)
            goto err;

        s_ccsid = u32_value;

        /* CCSID的位置是112,长度为4,整块长度为i_size=172 */
        bytebuff_skip(p_st_data, i_size - 116);
        ui_left_len -= i_size;
        ui_offset += i_size;

        frfree(p_data);
        if (ui_left_len < 4)
        {
            *p_ui_offset = ui_offset;
            *p_s_ccsid = s_ccsid;
            return FR_SUCC;
        }

        /* 取StructID */
        i_ret = __ibmmq_get_data_by_bytes(p_st_data, 4, &p_data);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    if (strncmp(p_data, IBMMQ_STRUCTID_MDE, 4) == 0
        || strncmp(p_data, IBMMQ_STRUCTID_CIH, 4) == 0
        || strncmp(p_data, IBMMQ_STRUCTID_IIH, 4) == 0
        || strncmp(p_data, IBMMQ_STRUCTID_RFH, 4) == 0
        || strncmp(p_data, IBMMQ_STRUCTID_RMH, 4) == 0
        || strncmp(p_data, IBMMQ_STRUCTID_WIH, 4) == 0)
    {
        /* 到CCSID为止的长度 */
        if (ui_left_len < 20)
        {
            frfree(p_data);
            return APM_L7_ANALYZE_TODO;
        }

        bytebuff_skip(p_st_data, 8);
        ui_left_len -= 8;

        /* 长度 */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)u32_byte_order);
        if (i_ret == FR_FAIL)
            goto err;

        ui_len = u32_value;
        ui_left_len -= 4;

        /* Encoding */
        bytebuff_skip(p_st_data, 4);
        ui_left_len -= 4;

        /* CCSID */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)u32_byte_order);
        if (i_ret == FR_FAIL)
            goto err;

        s_ccsid = u32_value;
        ui_left_len -= 4;

        if (ui_left_len < 20)
        {
            frfree(p_data);
            return APM_L7_ANALYZE_TODO;
        }

        bytebuff_skip(p_st_data, 20);
        ui_left_len -= 20;

        /* JMS数据 */
        ui_jms_len = ui_len - 40;
        if (ui_left_len < ui_jms_len)
        {
            frfree(p_data);
            return APM_L7_ANALYZE_TODO;
        }

        if (p_st_private->p_st_l7_session == NULL)
            goto err;
        /* JMS数据解析 */
        i_ret = __ibmmq_jms_data_analysis(p_st_private, p_st_body_data
                                        , p_st_data, ui_jms_len, p_report_pre);
        if (i_ret == FR_FAIL)
            goto err;

        ui_left_len -= ui_jms_len;
        ui_offset = ui_len;
    }

    *p_ui_offset = ui_offset;
    *p_s_ccsid = s_ccsid;

    frfree(p_data);
    return FR_SUCC;

err:
    frfree(p_data);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  MAP数据上报
*  ARGS     :  p_st_body_data(上报链表)
            :  p_map_data(MAP数据)
            :  p_key_pre(key的前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_map_report(Frreport_body_data *p_st_body_data
                               , char *p_key
                               , char *p_value
                               , char *p_type_value)
{
    int i_value = 0;
    long l_value = 0;
    float f_value = 0;
    double db_value = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_key == NULL || p_value == NULL)
        return FR_FAIL;

    if (p_type_value == NULL)
    {
        /* String类型上报 */
        if (frreport_body_l7_add_str(p_st_body_data, p_key, p_value) == FR_FAIL)
            return FR_FAIL;

        return FR_SUCC;
    }

    if (strcmp(p_type_value, IBMMQ_MAP_DATA_TYPE_CHAR) == 0)
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, p_value);
    else if (strcmp(p_type_value, IBMMQ_MAP_DATA_TYPE_BYTE) == 0
        || strcmp(p_type_value, IBMMQ_MAP_DATA_TYPE_SHORT) == 0
        || strcmp(p_type_value, IBMMQ_MAP_DATA_TYPE_INT) == 0)
    {
        i_value = atoi(p_value);
        i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, i_value);
    }
    else if (strcmp(p_type_value, IBMMQ_MAP_DATA_TYPE_LONG) == 0)
    {
        l_value = atol(p_value);
        i_ret = frreport_body_l7_add_long(p_st_body_data, p_key, l_value);
    }
    else if (strcmp(p_type_value, IBMMQ_MAP_DATA_TYPE_FLOAT) == 0)
    {
        f_value = strtof(p_value, NULL);

        i_ret = frreport_body_l7_add_float(p_st_body_data, p_key, f_value);
    }
    else if (strcmp(p_type_value, IBMMQ_MAP_DATA_TYPE_DOUBLE) == 0)
    {
        db_value = strtod(p_value, NULL);

        i_ret = frreport_body_l7_add_double(p_st_body_data, p_key, db_value);
    }

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  MAP数据解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_map_data(MAP数据)
            :  p_key_pre(key的前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_map_analysis(Frreport_body_data *p_st_body_data
                                 , char *p_map_data
                                 , char *p_key_pre)
{
    xmlDocPtr p_st_doc = NULL;
    xmlNodePtr p_st_root = NULL;
    xmlNodePtr p_st_current = NULL;
    xmlChar *p_content = NULL;
    xmlChar *p_key = NULL;
    xmlChar *p_type_value = NULL;
    char arr_key[64];
    int i_ret = 0;

    if (p_st_body_data == NULL || p_map_data == NULL || p_key_pre == NULL)
        return FR_FAIL;

    p_st_doc = xmlReadMemory(p_map_data, strlen(p_map_data), NULL, NULL, XML_PARSE_NOBLANKS|XML_PARSE_NOERROR|XML_PARSE_NOWARNING);
    if (p_st_doc == NULL)
        return FR_FAIL;

    /* 根节点 */
    p_st_root = xmlDocGetRootElement(p_st_doc);
    if (p_st_root == NULL)
        goto err;

    if (xmlStrcmp(p_st_root->name, (const xmlChar *) "map") != 0)
        goto err;

    p_st_current = xmlFirstElementChild(p_st_root);
    if (p_st_current == NULL)
        goto err;

    for (; p_st_current; p_st_current = p_st_current->next)
    {
        /* 取key值 */
        if (xmlHasProp(p_st_current, (xmlChar *)"name"))
        {
            p_key = xmlGetProp(p_st_current, (xmlChar *)"name");
            if (p_key == NULL)
                goto err;
        }

        /* 取value */
        p_content = xmlNodeGetContent(p_st_current);
        if (p_content == NULL)
            goto err;

        /* 取数据类型 */
        if (xmlHasProp(p_st_current, (xmlChar *)"dt"))
            p_type_value = xmlGetProp(p_st_current, (xmlChar *)"dt");

        memset(arr_key, 0x00, sizeof(arr_key));
        snprintf(arr_key, sizeof(arr_key), "%s%s", p_key_pre, (const char *)p_key);

        /* key-value上报 */
        i_ret = __ibmmq_map_report(p_st_body_data, (char *)arr_key, (char *)p_content, (char *)p_type_value);
        if (i_ret == FR_FAIL)
            goto err;

        xmlFree(p_key);
        xmlFree(p_content);
        p_content = NULL;
        if (p_type_value)
            xmlFree(p_type_value);
        p_type_value = NULL;
    }

    xmlFreeDoc(p_st_doc);
    return FR_SUCC;

 err:
    xmlFreeDoc(p_st_doc);
    if (p_key)
        xmlFree(p_key);
    if (p_content)
        xmlFree(p_content);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  GMO解析
*  ARGS     :  p_st_data(数据)
            :  p_ui_data_len(数据长度)
            :  u32_byte_order(数据读取方式)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_gmo_analysis(Frreport_body_data *p_st_body_data
                                 , Frbyte_Packet *p_st_data
                                 , L7Session_ibmmq *p_st_session
                                 , unsigned int *p_ui_data_len
                                 , uint32_t u32_byte_order)
{
    char arr_queue[49];
    unsigned int ui_left_len = 0;
    int i_size = 0;
    int i_ret = 0;
    uint32_t u32_version = 0;

    if (p_st_data == NULL || p_st_session == NULL || p_ui_data_len == NULL)
        return FR_FAIL;

    ui_left_len = *p_ui_data_len;
    if (ui_left_len < 8)
        return FR_FAIL;

    /* StructID */
    bytebuff_skip(p_st_data, 4);
    ui_left_len -= 4;

    /* 取得Version */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_version, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_left_len -= 4;

    /* 判断版本号 */
    switch (u32_version)
    {
        case 1: i_size = IBMMQ_GMO_V1_LEN;break;
        case 2: i_size = IBMMQ_GMO_V2_LEN;break;
        case 3: i_size = IBMMQ_GMO_V3_LEN;break;
    }

    if ((int)ui_left_len < i_size - 8)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, 16);
    memset(arr_queue, 0x00, sizeof(arr_queue));
    /* 取队列名 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_queue);
    ui_left_len -= 64;

    bytebuff_skip(p_st_data, i_size - 72);
    ui_left_len -= (i_size - 72);

    *p_ui_data_len = ui_left_len;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQADMIN消息(参数)解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  u32_msg_len(数据长度)
            :  p_method(method)
            :  u32_byte_order(数据读取方式)
            :  u32_count(parameter个数)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_data_analysis_admin_parm(Frreport_body_data *p_st_body_data
                                             , Frbyte_Packet *p_st_data
                                             , unsigned int u32_msg_len
                                             , char *p_method
                                             , uint32_t u32_byte_order
                                             , uint32_t u32_count)
{
    char arr_key[64];
    char arr_key1[64];
    char arr_report_pre[64];
    char arr_msgtype[64];
    char arr_size[64];
    uint32_t u32_type = 0;
    uint32_t u32_len = 0;
    uint32_t u32_ccsid = 0;
    uint32_t u32_str_len = 0;
    uint32_t u32_list_cnt = 0;
    int i_cnt = 0;
    int i_cnt2 = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL || p_method == NULL)
        return FR_FAIL;

    if (strcmp(p_method, "PUT") == 0)
    {
        snprintf(arr_msgtype, sizeof(arr_msgtype), "request.%s.1", MQ_REPOER_MQ_MSG_TYPE);
        snprintf(arr_size, sizeof(arr_size), "request.%s", MQ_MESSAGE_SIZE);
        snprintf(arr_report_pre, sizeof(arr_report_pre), "request.%s.%s", MQ_REPORT_MQ_MSG, IBMMQ_MSG_TYPE_LIST);
    }
    else if (strcmp(p_method, "NOTIFY") == 0)
    {
        snprintf(arr_msgtype, sizeof(arr_msgtype), "notify.%s.1", MQ_REPOER_MQ_MSG_TYPE);
        snprintf(arr_size, sizeof(arr_size), "notify.%s", MQ_MESSAGE_SIZE);
        snprintf(arr_report_pre, sizeof(arr_report_pre), "notify.%s.%s.1", MQ_REPORT_MQ_MSG, IBMMQ_MSG_TYPE_LIST);
    }
    else
    {
        snprintf(arr_msgtype, sizeof(arr_msgtype), "response.%s.1", MQ_REPOER_MQ_MSG_TYPE);
        snprintf(arr_size, sizeof(arr_size), "response.%s", MQ_MESSAGE_SIZE);
        snprintf(arr_report_pre, sizeof(arr_report_pre), "response.%s.%s.1", MQ_REPORT_MQ_MSG, IBMMQ_MSG_TYPE_LIST);
    }

    /* message.type上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_msgtype, IBMMQ_MSG_TYPE_LIST);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    for (; i_cnt < (int)u32_count; i_cnt++)
    {
        if (bytebuff_remaining(p_st_data) < 8)
            return APM_L7_ANALYZE_TODO;

        /* 类型 */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_type, (LITTLE_BIG_ENDIAN)u32_byte_order);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        /* 长度 */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, (LITTLE_BIG_ENDIAN)u32_byte_order);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        if (u32_len == 0)
            break;

        memset(arr_key, 0x00, sizeof(arr_key));
        snprintf(arr_key, sizeof(arr_key), "%s.%d", arr_report_pre, i_cnt+1);

        switch (u32_type)
        {
            case IBMMQ_MQCFT_NONE:
            case IBMMQ_MQCFT_COMMAND:
            case IBMMQ_MQCFT_RESPONSE:
                break;
            case IBMMQ_MQCFT_INTEGER:
            case IBMMQ_MQCFT_INTEGER_FILTER:
                if (bytebuff_remaining(p_st_data) < 8)
                    return APM_L7_ANALYZE_TODO;

                bytebuff_skip(p_st_data, 4);

                i_ret = __ibmmq_data_analysis_int(p_st_body_data, p_st_data, u32_byte_order, arr_key);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            case IBMMQ_MQCFT_STRING:
            case IBMMQ_MQCFT_STRING_FILTER:
                if (bytebuff_remaining(p_st_data) < 12)
                    return APM_L7_ANALYZE_TODO;

                bytebuff_skip(p_st_data, 4);

                /* CCSID */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_ccsid, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                /* String长度 */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_str_len, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                i_ret = __ibmmq_data_analysis_str(p_st_body_data, p_st_data, u32_byte_order, arr_key, u32_ccsid, u32_str_len);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                /* padding */
                if (bytebuff_remaining(p_st_data) >= (int)(u32_len - u32_str_len - 20))
                    bytebuff_skip(p_st_data, u32_len - u32_str_len - 20);

                break;
            case IBMMQ_MQCFT_INTEGER_LIST:
                if (bytebuff_remaining(p_st_data) < 8)
                    return APM_L7_ANALYZE_TODO;

                bytebuff_skip(p_st_data, 4);

                /* list个数 */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_list_cnt, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                if (bytebuff_remaining(p_st_data) < (int)(4*u32_list_cnt))
                    return APM_L7_ANALYZE_TODO;

                i_ret = __ibmmq_data_analysis_intlist(p_st_body_data, p_st_data, u32_byte_order, arr_key, u32_list_cnt);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                break;
            case IBMMQ_MQCFT_STRING_LIST:
                if (bytebuff_remaining(p_st_data) < 16)
                    return APM_L7_ANALYZE_TODO;

                bytebuff_skip(p_st_data, 4);

                /* CCSID */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_ccsid, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                /* list个数 */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_list_cnt, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                /* String长度 */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_str_len, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                if (bytebuff_remaining(p_st_data) < (int)(u32_str_len*u32_list_cnt))
                    return APM_L7_ANALYZE_TODO;

                i_ret = __ibmmq_data_analysis_stringlist(p_st_body_data, p_st_data, u32_byte_order, arr_key, u32_ccsid, u32_str_len, u32_list_cnt);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            case IBMMQ_MQCFT_USER:
                if (bytebuff_remaining(p_st_data) < (int)(u32_len - 8))
                    return APM_L7_ANALYZE_TODO;

                strcat(arr_key, IBMMQ_MSG_TYPE_TEXT);

                i_ret = __ibmmq_data_analysis_str(p_st_body_data, p_st_data, u32_byte_order, arr_key, 0, u32_len - 8);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            case IBMMQ_MQCFT_BYTE_STRING:
            case IBMMQ_MQCFT_BYTE_STRING_FILTER:
                if (bytebuff_remaining(p_st_data) < 8)
                    return APM_L7_ANALYZE_TODO;

                bytebuff_skip(p_st_data, 4);
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_str_len, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                strcat(arr_key, IBMMQ_MSG_TYPE_OBJ);

                i_ret = __ibmmq_data_analysis_bin(p_st_body_data, p_st_data, u32_byte_order, arr_key, u32_str_len);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            case IBMMQ_MQCFT_INTEGER64:
                if (bytebuff_remaining(p_st_data) < 12)
                    return APM_L7_ANALYZE_TODO;

                bytebuff_skip(p_st_data, 4);

                strcat(arr_key, IBMMQ_MSG_TYPE_TEXT);

                i_ret = __ibmmq_data_analysis_long(p_st_body_data, p_st_data, u32_byte_order, arr_key);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            case IBMMQ_MQCFT_INTEGER64_LIST:
                if (bytebuff_remaining(p_st_data) < 12)
                    return APM_L7_ANALYZE_TODO;

                bytebuff_skip(p_st_data, 4);

                /* list个数 */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_list_cnt, (LITTLE_BIG_ENDIAN)u32_byte_order);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                if (bytebuff_remaining(p_st_data) < (int)(8*u32_list_cnt))
                    return APM_L7_ANALYZE_TODO;

                for (i_cnt2 = 0; i_cnt2 < (int)u32_list_cnt; i_cnt2++)
                {
                    memset(arr_key1, 0x00, sizeof(arr_key1));
                    snprintf(arr_key1, sizeof(arr_key1), "%s%s.%d", arr_key, IBMMQ_MSG_TYPE_LIST, i_cnt2+1);

                    i_ret = __ibmmq_data_analysis_long(p_st_body_data, p_st_data, u32_byte_order, arr_key1);
                    if (i_ret == FR_FAIL)
                        return FR_FAIL;
                }
                break;
            default :
                break;
        }
    }

    // 消息个数上报
    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_size, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQADMIN消息解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  u32_msg_len(数据长度)
            :  p_method(method)
            :  u32_byte_order(数据读取方式)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_data_analysis_admin(Frreport_body_data *p_st_body_data
                                        , Frbyte_Packet *p_st_data
                                        , unsigned int u32_msg_len
                                        , char *p_method
                                        , uint32_t u32_byte_order)
{
    uint32_t u32_count = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL || p_method == NULL)
        return FR_FAIL;

    if (u32_msg_len < 36)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, 32);

    /* 参数个数 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_count, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    u32_msg_len -= 36;

    i_ret = __ibmmq_data_analysis_admin_parm(p_st_body_data, p_st_data, u32_msg_len
                                           , p_method, u32_byte_order, u32_count);
    return i_ret;
}

/*******************************************************************************
*  FUNC     :  消息上报
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ibmmq_msg_data_analysis(Frreport_body_data *p_st_body_data
                                      , L7session_ibmmq_private *p_st_private
                                      , Frbyte_Packet *p_st_data
                                      , char *p_data
                                      , unsigned int ui_data_len
                                      , int i_msg_type
                                      , char *p_key
                                      , int i_req_resp
                                      , int i_xml_todo
                                      , short s_ccsid)
{
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    char arr_key[64];
    char arr_type_key[64];
    char *p_iconv_outbuf = NULL;
    char *p_code_string = NULL;
    char *p_err_msg = NULL;
    unsigned int ui_iconv_outlen = 0;
    int i_ret = 0;


    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL || p_key == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    memset(arr_key, 0x00, sizeof(arr_key));
    memset(arr_type_key, 0x00, sizeof(arr_type_key));
    switch (i_msg_type)
    {
        case IBMMQ_MSG_TYPE_MAP_FLG:
            if (i_req_resp == IBMMQ_REQUEST)
                snprintf(arr_key, sizeof(arr_key), "%s%s.", p_key, MQ_REPORT_MQ_MSG_MAP);
            else
                snprintf(arr_key, sizeof(arr_key), "%s%s.1.", p_key, MQ_REPORT_MQ_MSG_MAP);

            if (__ibmmq_map_analysis(p_st_body_data, p_data, arr_key) == FR_FAIL)
                return FR_FAIL;

            frfree(p_data);
            break;
        case IBMMQ_MSG_TYPE_OBJ_FLG:
            if (i_req_resp == IBMMQ_REQUEST)
                snprintf(arr_key, sizeof(arr_key), "%s%s", p_key, MQ_REPORT_MQ_MSG_OBJ);
            else
                snprintf(arr_key, sizeof(arr_key), "%s%s.1", p_key, MQ_REPORT_MQ_MSG_OBJ);

            /* binary数据上报 */
            if (frreport_body_l7_add_bin(p_st_body_data, arr_key, p_data, ui_data_len) == FR_FAIL)
                return FR_FAIL;

            frfree(p_data);
            break;
        case IBMMQ_MSG_TYPE_TEXT_FLG:
        default:
            if (i_req_resp == IBMMQ_REQUEST)
                snprintf(arr_key, sizeof(arr_key), "%s%s", p_key, MQ_REPORT_MQ_MSG_TEXT);
            else
                snprintf(arr_key, sizeof(arr_key), "%s%s.1", p_key, MQ_REPORT_MQ_MSG_TEXT);

            if (s_ccsid == 0)
                s_ccsid = p_st_head->s_ccsid;

            /* 没有数据 */
            if (ui_data_len == 0)
            {
                i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, "");
                return i_ret;
            }

            /* 数据转换成UTF-8 */
            i_ret = ibmmq_str_to_utf8(s_ccsid, p_data, ui_data_len
                                    , &p_iconv_outbuf, &ui_iconv_outlen);
            frfree(p_data);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            /* default以外的message.type在__ibmmq_jms_data_analysis中已经上报 */
            if (p_st_private->i_msg_type != IBMMQ_MSG_TYPE_TEXT_FLG)
            {
                if (i_req_resp == IBMMQ_REQUEST)
                    snprintf(arr_type_key, sizeof(arr_type_key), "%s%s", p_key, MQ_REPOER_MQ_MSG_TYPE);
                else
                    snprintf(arr_type_key, sizeof(arr_type_key), "%s%s.1", p_key, MQ_REPOER_MQ_MSG_TYPE);

                /* message.type上报 */
                if (frreport_body_l7_add_str(p_st_body_data, arr_type_key, IBMMQ_MSG_TYPE_TEXT) == FR_FAIL)
                {
                    frfree(p_data);
                    return FR_FAIL;
                }
            }

            if (frxml_detect(p_iconv_outbuf, ui_iconv_outlen) == FR_SUCC)
            {
                /* xml数据要完整上报 */
                if (i_xml_todo == 1)
                    return APM_L7_ANALYZE_TODO;


                if (strcasestr(p_iconv_outbuf, "soap") != NULL && strcasestr(p_iconv_outbuf, "Envelope") != NULL)
                {
                    /* 进行soap解析 */
                    if (i_req_resp == IBMMQ_REQUEST)
                        i_ret = frsoap_parse_req(p_iconv_outbuf, ui_iconv_outlen, p_st_body_data);
                    else
                        i_ret = frsoap_parse_resp(p_iconv_outbuf, ui_iconv_outlen, p_st_body_data, &p_code_string, &p_err_msg);
                    if (i_ret == FR_FAIL)
                    {
                        frfree(p_iconv_outbuf);
                        return FR_FAIL;
                    }
                    if (p_code_string && p_err_msg)
                    {
                        if (frreport_body_l7_add_int(p_st_body_data, APM_REPORT_KEY_RESP_CODE, 500) == FR_FAIL)
                        {
                            frfree(p_iconv_outbuf);
                            frfree(p_code_string);
                            frfree(p_err_msg);
                            return FR_FAIL;
                        }

                        if (frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_RESP_CODE_STRING, p_code_string) == FR_FAIL)
                        {
                            frfree(p_iconv_outbuf);
                            frfree(p_code_string);
                            frfree(p_err_msg);
                            return FR_FAIL;
                        }
                        frfree(p_code_string);

                        if (frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_RESP_ERR_MSG, p_err_msg) == FR_FAIL)
                        {
                            frfree(p_iconv_outbuf);
                            frfree(p_err_msg);
                            return FR_FAIL;
                        }
                        frfree(p_err_msg);
                    }
                }

                /* xml数据完整上报 */
                if (frreport_body_l7_add_str(p_st_body_data, arr_key, p_iconv_outbuf) == FR_FAIL)
                {
                    frfree(p_iconv_outbuf);
                    return FR_FAIL;
                }
                frfree(p_iconv_outbuf);
                break;
            }

            /* text数据上报 */
            if (FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, arr_key, p_iconv_outbuf) == FR_FAIL)
            {
                frfree(p_iconv_outbuf);
                return FR_FAIL;
            }
            frfree(p_iconv_outbuf);

            /* 大数据处理 */
            if (p_st_private->p_st_fragment->u64_left_len != 0)
            {
                bytebuff_set_skip(p_st_data, p_st_private->p_st_fragment->u64_left_len);
                return APM_L7_ANALYZE_TODO;
            }
            break;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  INITIAL_DATA解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_initial_analysis(Frreport_body_data *p_st_body_data
                                   , L7session_ibmmq_private *p_st_private
                                   , Frbyte_Packet *p_st_data
                                   , unsigned int ui_data_len
                                   , char *p_report_pre)
{
    int i_ret = 0;
    uint32_t u32_byte_order = 0;
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    char arr_tmp[21];

    memset(arr_tmp, 0x00, sizeof(arr_tmp));

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;

    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    u32_byte_order = p_st_head->u32_byte_order;

    if (ui_data_len < 44)
        return APM_L7_ANALYZE_TODO;

    /* 定位到通道位置 */
    bytebuff_skip(p_st_data, 24);

    /* 通道名 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 20);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_tmp);

    if (p_st_session->p_chanel == NULL)
    {
        p_st_session->p_chanel = frstrdup(arr_tmp);
        if (p_st_session->p_chanel == NULL)
            return FR_FAIL;
    }

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  USERID_DATA解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_userid_analysis(Frreport_body_data *p_st_body_data
                                  , L7session_ibmmq_private *p_st_private
                                  , Frbyte_Packet *p_st_data
                                  , unsigned int ui_data_len
                                  , char *p_report_pre)
{
    int i_ret = 0;
    uint32_t u32_byte_order = 0;
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    char arr_tmp[13];
    char arr_key[64];

    memset(arr_tmp, 0x00, sizeof(arr_tmp));
    memset(arr_key, 0x00, sizeof(arr_key));

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;

    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    u32_byte_order = p_st_head->u32_byte_order;

    /* StructID(4) + UserId(12) + Password(12) */
    if (ui_data_len < 28)
        return APM_L7_ANALYZE_TODO;

    /* 定位到User ID位置 */
    bytebuff_skip(p_st_data, 4);

    /* User ID */
    i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 12);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_tmp);

    /* 登陆名 */
    if (p_st_session->p_username == NULL)
    {
        p_st_session->p_username = frstrdup(arr_tmp);
        if (p_st_session->p_username == NULL)
            return FR_FAIL;
    }

    /* login成功的时间 */
    if (p_st_session->st_login.tv_sec == 0 && p_st_session->st_login.tv_usec == 0)
    {
        p_st_session->st_login.tv_sec = p_st_private->st_trans_info.st_l4_trans.st_request_time.tv_sec;
        p_st_session->st_login.tv_usec = p_st_private->st_trans_info.st_l4_trans.st_request_time.tv_usec;
    }

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  OPEN解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_open_analysis(L7session_ibmmq_private *p_st_private
                                , Frbyte_Packet *p_st_data
                                , unsigned int ui_data_len)
{
    L7Session_ibmmq *p_st_session = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    char arr_queue[49];
    int i_od_idx = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_lst_queue = p_st_session->p_lst_queue;

    /* 取队列名 */
    if (p_st_session->p_queue == NULL)
    {
        /* 找OD */
        i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, IBMMQ_OD_STRUCTID, 2, &i_od_idx);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        bytebuff_setPosition(p_st_data, i_od_idx+12);
        memset(arr_queue, 0x00, sizeof(arr_queue));
        /* 取队列名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_queue);

        if (*arr_queue == '\0')
            return FR_SUCC;

        /* add */
        i_ret = ibmmq_queue_list_add(p_st_session, arr_queue, 0);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        return FR_SUCC;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  OPEN_REPLY解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_openreply_analysis(L7session_ibmmq_private *p_st_private
                                , Frbyte_Packet *p_st_data
                                , unsigned int ui_data_len)
{
    L7Session_ibmmq *p_st_session = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    Queue_lst_ibmmq *p_st_queue = NULL;
    L7_head_ibmmq *p_st_head = NULL;
    char arr_queue[49];
    uint32_t u32_hdl = 0;
    int i_od_idx = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_lst_queue = p_st_session->p_lst_queue;

    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 12);
    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 队列名 */
    /* 找OD */
    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, IBMMQ_OD_STRUCTID, 2, &i_od_idx);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_setPosition(p_st_data, i_od_idx+12);
    memset(arr_queue, 0x00, sizeof(arr_queue));
    /* 取队列名 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_queue);

    if (*arr_queue == '\0')
        return FR_SUCC;

    /* 队列名查找 */
    p_st_queue = ibmmq_queue_list_queue_find(p_lst_queue, arr_queue);
    if (p_st_queue)
    {
        if (p_st_queue->u32_hdl == 0)
            p_st_queue->u32_hdl = u32_hdl;
        return FR_SUCC;
    }

    /* add */
    i_ret = ibmmq_queue_list_add(p_st_session, arr_queue, u32_hdl);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  SPI解析
*  ARGS     :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_spi_analysis(L7session_ibmmq_private *p_st_private
                               , Frbyte_Packet *p_st_data
                               , unsigned int ui_data_len
                               , char *p_report_pre)
{
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    Queue_lst_ibmmq *p_st_queue = NULL;
    uint32_t u32_spi_type = 0;
    uint32_t u32_topic_len = 0;
    uint32_t u32_hdl = 0;
    char arr_queue[49];
    char *p_topic = NULL;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    p_lst_queue = p_st_session->p_lst_queue;

    if (ui_data_len < 20)
        return APM_L7_ANALYZE_TODO;

    /* API Header长度为16(12+Hdl) */
    bytebuff_skip(p_st_data, 12);
    ui_data_len -= 12;

    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    ui_data_len -= 4;

    /* SPI类型(QUERY/OPEN/Unknown) */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_spi_type, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* SPI类型为QUERY时不做解析 */
    if (u32_spi_type == IBMMQ_SPI_TYPE_QUERY || u32_spi_type == IBMMQ_SPI_TYPE_UNKNOWN)
        return FR_SUCC;

    /* 160=64+68+48 */
    if (ui_data_len < 160)
        return APM_L7_ANALYZE_TODO;

    /* SPI(8) + SPOU(12) + SPOI(12) + LPOO(32) */
    bytebuff_skip(p_st_data, 64+68);
    ui_data_len -= 132;

    memset(arr_queue, 0x00, sizeof(arr_queue));
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_queue);

    if (*arr_queue != '\0')
    {
        /* 队列名查找 */
        p_st_queue = ibmmq_queue_list_queue_find(p_lst_queue, arr_queue);
        if (p_st_queue)
        {
            if (p_st_queue->u32_hdl == 0)
                p_st_queue->u32_hdl = u32_hdl;
            return FR_SUCC;
        }

        /* add */
        i_ret = ibmmq_queue_list_add(p_st_session, arr_queue, u32_hdl);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        return FR_SUCC;
    }

    /* 340=292+48 */
    if (ui_data_len < 340)
        return FR_FAIL;

    /* topic */
    bytebuff_skip(p_st_data, 288);
    ui_data_len -= 288;

    i_ret = bytebuff_get_int(p_st_data, 4, &u32_topic_len, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 48);
    ui_data_len -= 48;

    if (ui_data_len < u32_topic_len)
        return FR_FAIL;

    if (u32_topic_len == 0)
        return FR_SUCC;

    p_topic = (char *)frmalloc(u32_topic_len + 1);
    if (p_topic == NULL)
        return FR_FAIL;
    memset(p_topic, 0x00, u32_topic_len + 1);

    i_ret = bytebuff_get_bytes(p_st_data, p_topic, u32_topic_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_topic);
        return FR_FAIL;
    }

    /* 队列名查找 */
    p_st_queue = ibmmq_queue_list_queue_find(p_lst_queue, p_topic);
    if (p_st_queue)
    {
        if (p_st_queue->u32_hdl == 0)
            p_st_queue->u32_hdl = u32_hdl;
        return FR_SUCC;
    }

    /* add */
    i_ret = ibmmq_queue_list_add(p_st_session, p_topic, u32_hdl);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  SPI_REPLY解析
*  ARGS     :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_spireply_analysis(L7session_ibmmq_private *p_st_private
                               , Frbyte_Packet *p_st_data
                               , unsigned int ui_data_len
                               , char *p_report_pre)
{
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    Queue_lst_ibmmq *p_st_queue = NULL;
    char arr_queue[49];
    uint32_t u32_hdl = 0;
    int i_od_idx = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    p_lst_queue = p_st_session->p_lst_queue;

    bytebuff_skip(p_st_data, 12);
    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, IBMMQ_OD_STRUCTID, 2, &i_od_idx);
    if (i_ret == FR_FAIL)
        return FR_SUCC;

    bytebuff_setPosition(p_st_data, i_od_idx+12);
    memset(arr_queue, 0x00, sizeof(arr_queue));

    /* 取队列名 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_queue);

    if (*arr_queue == '\0')
        return FR_SUCC;

    /* 在链表中找 */
    if (p_lst_queue)
    {
        p_st_queue = ibmmq_queue_list_queue_find(p_lst_queue, arr_queue);
        if (p_st_queue)
            p_st_queue->u32_hdl = u32_hdl;
    }
    else
    {
        i_ret = ibmmq_queue_list_add(p_st_session, arr_queue, u32_hdl);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  SUB解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_sub_analysis(Frreport_body_data *p_st_body_data
                               , L7session_ibmmq_private *p_st_private
                               , Frbyte_Packet *p_st_data
                               , unsigned int ui_data_len)
{
    L7Session_ibmmq *p_st_session = NULL;
    char arr_queue[49];
    char arr_title[64];
    memset(arr_title, 0x00, sizeof(arr_title));
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;

    if (ui_data_len < 84)
        return APM_L7_ANALYZE_TODO;

    /* 16为API Header长度 */
    bytebuff_skip(p_st_data, 16+20);

    memset(arr_queue, 0x00, sizeof(arr_queue));
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_queue);

    /* 添加到session */
    if (p_st_session->p_queue)
        frfree(p_st_session->p_queue);

    p_st_session->p_queue = frstrdup(arr_queue);
    if (p_st_session->p_queue == NULL)
        return FR_FAIL;

    /* 设置title */
    snprintf(arr_title, sizeof(arr_title), "SUB %s", p_st_session->p_queue);
    if (p_st_session->p_title)
        frfree(p_st_session->p_title);

    p_st_session->p_title = frstrdup(arr_title);
    if (p_st_session->p_title == NULL)
        return FR_FAIL;

    /* subscription.mq.queue上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_SUB_QUE, arr_queue);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    p_st_private->i_pubsub_flag = IBMMQ_MSG_SUB;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQPUT解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
            :  i_type(IBMMQ_MQPUT/IBMMQ_MQPUT1)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_put_analysis(Frreport_body_data *p_st_body_data
                               , L7session_ibmmq_private *p_st_private
                               , Frbyte_Packet *p_st_data
                               , unsigned int ui_data_len
                               , char *p_report_pre
                               , int i_type)
{
    unsigned int ui_left_len = ui_data_len;
    unsigned int ui_len = 0;
    unsigned int ui_submd_len = 0;
    unsigned int ui_report_len = 0;
    short s_ccsid = 0;
    int i_ret = 0;
    int i_md_idx = 0;
    int i_od_idx = 0;
    int i_xml_todo = 0;
    uint32_t u32_value = 0;
    uint32_t u32_hdl = 0;
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    Queue_lst_ibmmq *p_st_queue = NULL;
    char *p_data = NULL;
    char arr_queue[49];
    memset(arr_queue, 0x00, sizeof(arr_queue));
    char arr_title[64];
    memset(arr_title, 0x00, sizeof(arr_title));
    char arr_type_key[64];
    memset(arr_type_key, 0x00, sizeof(arr_type_key));
    char arr_format[9];
    memset(arr_format, 0x00, sizeof(arr_format));

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    p_lst_queue = p_st_session->p_lst_queue;
    bytebuff_skip(p_st_data, 12);
    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    ui_left_len -= 16;

    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, IBMMQ_MQMD_STRUCTID, 2, &i_md_idx);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

//    i_md_idx = i_md_idx - bytebuff_getPosition(p_st_data);
    if ((int)ui_left_len < i_md_idx - bytebuff_getPosition(p_st_data))
        return APM_L7_ANALYZE_TODO;

    /* 没有从SPI里取到queue,从OD里取 */
    if (p_st_session->p_queue == NULL || i_type == IBMMQ_MQPUT1)
    {
        i_ret = bytebuff_memstr(p_st_data, 0, i_md_idx, IBMMQ_OD_STRUCTID, 2, &i_od_idx);
        if (i_ret == FR_SUCC)
        {
            /* OD的structid(4)+version(4)+objtype(4) */
            bytebuff_setPosition(p_st_data, i_od_idx+12);

            /* 取queue名 */
            i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            frrtrim(arr_queue);

            /* MQPUT1的队列名从OD里取 */
            if (i_type == IBMMQ_MQPUT1 && p_st_session->p_queue != NULL)
                frfree(p_st_session->p_queue);

            p_st_session->p_queue = frstrdup(arr_queue);
            if (p_st_session->p_queue == NULL)
                return FR_FAIL;

            i_od_idx += 60;
        }
    }

    /* 用Hdl找到对应的队列名 */
    if (i_type == IBMMQ_MQPUT)
    {
        p_st_queue = ibmmq_queue_list_hdl_find(p_lst_queue, u32_hdl);
        if (p_st_queue)
        {
            if (p_st_session->p_queue)
                frfree(p_st_session->p_queue);

            p_st_session->p_queue = frstrdup(p_st_queue->arr_queue);
            if (p_st_session->p_queue == NULL)
                return FR_FAIL;
        }
    }

    /* 设置title */
    if (p_st_session->p_queue != NULL)
    {
        snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_session->p_queue);
        if (p_st_session->p_title)
            frfree(p_st_session->p_title);

        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;

        /* request.mq.queue上报 */
        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQ_QUE, p_st_session->p_queue);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        if (p_st_session->p_title)
            frfree(p_st_session->p_title);

        p_st_session->p_title = frstrdup("PUT");
        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }

    /* mq.method上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD, "PUT");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

//    bytebuff_skip(p_st_data, i_md_idx-i_od_idx);
//    ui_left_len -= (i_md_idx-i_od_idx);

    bytebuff_setPosition(p_st_data, i_md_idx);
    ui_left_len = bytebuff_remaining(p_st_data);

    /* MQMD解析 */
    i_ret = __ibmmq_md_analysis(p_st_private, p_st_body_data, p_st_head->u32_byte_order
                              , p_st_data, &ui_left_len, &s_ccsid, IBMMQ_REQUEST, arr_format);
    if (i_ret != FR_SUCC)
        return i_ret;

    /* 跳过PMO */
    i_ret = __ibmmq_pmo_analysis(p_st_data, &ui_left_len, p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (ui_left_len < 4)
        return APM_L7_ANALYZE_TODO;

    /* Data Len */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_len = u32_value;

    ui_left_len -= 4;

    /* 结构化数据头部解析 */
    i_ret = __ibmmq_submd_analysis(p_st_private, p_st_body_data, p_st_data
                                 , ui_left_len, p_report_pre, &ui_submd_len, &s_ccsid);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_left_len -= ui_submd_len;

    if (ui_left_len < ui_len - ui_submd_len && ui_left_len < APM_REPORT_MQ_MAX)
    {
        /* 当前解析的数据包只是消息的一部分，后面还有消息的后半部分 */
        if (p_st_private->p_st_fragment->u64_left_len == 0)
        {
            /* 还需要的消息内容的长度 */
            p_st_private->ui_left_msgfragment_len = ui_len - ui_submd_len - ui_left_len;
            p_st_private->i_msgfragment_flag = 1;
        }
        return APM_L7_ANALYZE_TODO;
    }

    if (ui_left_len != 0)
    {
        /* MQADMIN消息解析 */
        if (strncmp(arr_format, IBMMQ_MQFMT_ADMIN, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_EVENT, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_PCF, 8) == 0)
        {
            i_ret = __ibmmq_data_analysis_admin(p_st_body_data, p_st_data, ui_len, (char *)"PUT", p_st_head->u32_byte_order);
            return i_ret;
        }

        ui_report_len = ui_left_len < ui_len - ui_submd_len ? ui_left_len : ui_len - ui_submd_len;

        p_data = (char *)frmalloc(ui_report_len + 1);
        if (p_data == NULL)
            return FR_FAIL;
        memset(p_data, 0x00, ui_report_len + 1);

        i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_report_len);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
    }

    /* xml数据需要完整上报，如果i_xml_todo为1并且数据为xml格式，返回todo */
    if (ui_left_len < ui_len - ui_submd_len)
        i_xml_todo = 1;

    i_ret = __ibmmq_msg_data_analysis(p_st_body_data, p_st_private, p_st_data, p_data, ui_report_len
                                    , p_st_private->i_msg_type, p_report_pre, IBMMQ_REQUEST, i_xml_todo, s_ccsid);
    return i_ret;
}

/*******************************************************************************
*  FUNC     :  MQPUT_REPLY解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
            :  i_type(IBMMQ_MQPUT/IBMMQ_MQPUT1)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_putreply_analysis(Frreport_body_data *p_st_body_data
                               , L7session_ibmmq_private *p_st_private
                               , Frbyte_Packet *p_st_data
                               , unsigned int ui_data_len)
{
    L7_head_ibmmq *p_st_head = NULL;
    uint32_t u32_reason_code = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_body_data == NULL
        || p_st_data == NULL || p_st_private->p_st_head == NULL)
        return FR_FAIL;

    p_st_head = p_st_private->p_st_head;

    if (ui_data_len < 16)
        return APM_L7_ANALYZE_TODO;

    /* 长度+返回码 */
    bytebuff_skip(p_st_data, 8);

    /* 取原因码 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_reason_code, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 结果上报 */
    i_ret = frreport_body_l7_add_int(p_st_body_data, IBMMQ_RESP_CODE, u32_reason_code);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* code_string上报 */
    i_ret = frreport_body_l7_add_int(p_st_body_data, IBMMQ_RESP_CODE_STRING, u32_reason_code);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  IBMMQ_REQUEST_MSGS解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_data(数据)
            :  p_st_private(IBM MQ私有数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_requestmsg_analysis(Frreport_body_data *p_st_body_data
                                      , Frbyte_Packet *p_st_data
                                      , L7session_ibmmq_private *p_st_private)
{
    L7Session_ibmmq *p_st_session = NULL;
    L7_head_ibmmq *p_st_head = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    Queue_lst_ibmmq *p_st_queue = NULL;
    char arr_title[64];
    memset(arr_title, 0x00, sizeof(arr_title));
    uint32_t u32_hdl = 0;
    uint32_t u32_reqflag = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL
        || p_st_private->p_st_head == NULL)
        return FR_FAIL;

    p_st_head = p_st_private->p_st_head;
    p_st_session = p_st_private->p_st_l7_session;
    if (bytebuff_remaining(p_st_data) < 32)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 4);
    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 24);
    /* 取request flag */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_reqflag, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    p_lst_queue = p_st_session->p_lst_queue;
    /* 用Hdl找到对应的队列名 */
    p_st_queue = ibmmq_queue_list_hdl_find(p_lst_queue, u32_hdl);
    if (p_st_queue)
    {
        if (p_st_session->p_queue)
            frfree(p_st_session->p_queue);

        p_st_session->p_queue = frstrdup(p_st_queue->arr_queue);
        if (p_st_session->p_queue == NULL)
            return FR_FAIL;
    }

    if (p_st_session->p_queue)
    {
        /* 设置title */
        if (u32_reqflag == 26)
            snprintf(arr_title, sizeof(arr_title), "NOTIFY %s", p_st_session->p_queue);
        else
            snprintf(arr_title, sizeof(arr_title), "GET %s", p_st_session->p_queue);

        if (p_st_session->p_title)
            frfree(p_st_session->p_title);

        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }
    else
    {
        if (p_st_session->p_title)
            frfree(p_st_session->p_title);

        /* 设置title */
        if (u32_reqflag == 26)
            p_st_session->p_title = frstrdup("NOTIFY");
        else
            p_st_session->p_title = frstrdup("GET");

        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }

    /* mq.method上报 */
    if (u32_reqflag == 26)
    {
        p_st_private->i_pubsub_flag = IBMMQ_MSG_NOTIFY;
        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD, "NOTIFY");
    }
    else
        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD, "GET");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  ASYNC_MESSAGE解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_async_msg_analysis(Frreport_body_data *p_st_body_data
                                     , L7session_ibmmq_private *p_st_private
                                     , Frbyte_Packet *p_st_data
                                     , unsigned int ui_data_len
                                     , char *p_report_pre)
{
    int i_ret = 0;
    int i_md_idx = 0;
    int i_offset = 0;
    int i_xml_todo = 0;
    unsigned int ui_left_len = ui_data_len;
    unsigned int ui_segmlen = 0;
    unsigned int ui_submd_len = 0;
    unsigned int ui_report_len = 0;
    uint32_t u32_byte_order = 0;
    uint32_t u32_value = 0;
    uint32_t u32_hdl = 0;
    short s_ccsid = 0;
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    char *p_data = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    Queue_lst_ibmmq *p_st_queue = NULL;
    char arr_type_key[64];
    memset(arr_type_key, 0x00, sizeof(arr_type_key));
    char arr_title[64];
    memset(arr_title, 0x00, sizeof(arr_title));
    char arr_format[9];
    memset(arr_format, 0x00, sizeof(arr_format));
    char arr_report_key[64];
    memset(arr_report_key, 0x00, sizeof(arr_report_key));
    char arr_size[64];

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    u32_byte_order = p_st_head->u32_byte_order;

    /* SegLength的offset(20) */
    if (ui_left_len < 20)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, 4);
    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 8);

    /* SegLength */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_value, (LITTLE_BIG_ENDIAN)u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_segmlen = u32_value;
    ui_left_len -= 20;

    /* 找到MD */
    i_offset = bytebuff_getPosition(p_st_data);
    if (i_offset == -1)
        return FR_FAIL;
    i_ret = bytebuff_memstr(p_st_data, i_offset, 0, IBMMQ_MQMD_STRUCTID, 2, &i_md_idx);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    i_md_idx = i_md_idx - bytebuff_getPosition(p_st_data);
    if ((int)ui_left_len < i_md_idx)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, i_md_idx);
    ui_left_len -= i_md_idx;

    /* MQMD解析 */
    i_ret = __ibmmq_md_analysis(p_st_private, p_st_body_data, p_st_head->u32_byte_order
                              , p_st_data, &ui_left_len, &s_ccsid, IBMMQ_RESPONSE, arr_format);
    if (i_ret != FR_SUCC)
        return i_ret;

    /* 结构化数据头部解析 */
    i_ret = __ibmmq_submd_analysis(p_st_private, p_st_body_data, p_st_data
                                 , ui_left_len, p_report_pre, &ui_submd_len, &s_ccsid);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_left_len -= ui_submd_len;

    if (ui_left_len < ui_segmlen - ui_submd_len && ui_left_len < APM_REPORT_MQ_MAX)
    {
        /* 当前解析的数据包只是消息的一部分，后面还有消息的后半部分 */
        if (p_st_private->p_st_fragment->u64_left_len == 0)
        {
            /* 还需要的消息内容的长度 */
            p_st_private->ui_left_msgfragment_len = ui_segmlen - ui_submd_len - ui_left_len;
            p_st_private->i_msgfragment_flag = 1;
        }
        return APM_L7_ANALYZE_TODO;
    }
    if (ui_left_len != 0)
    {
        /* MQADMIN消息解析 */
        if (strncmp(arr_format, IBMMQ_MQFMT_ADMIN, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_EVENT, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_PCF, 8) == 0)
        {
            i_ret = __ibmmq_data_analysis_admin(p_st_body_data, p_st_data, ui_segmlen, (char *)"NOTIFY", p_st_head->u32_byte_order);
            return i_ret;
        }

        ui_report_len = ui_left_len < ui_segmlen - ui_submd_len ? ui_left_len : ui_segmlen - ui_submd_len;

        /* Data */
        p_data = (char *)frmalloc(ui_report_len + 1);
        if (p_data == NULL)
            return FR_FAIL;
        memset(p_data, 0x00, ui_report_len + 1);

        i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_report_len);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
    }

    snprintf(arr_report_key, sizeof(arr_report_key), "%s.", APM_REPORT_KEY_NOTIFY);

    p_lst_queue = p_st_session->p_lst_queue;
    /* 用Hdl找到对应的队列名 */
    p_st_queue = ibmmq_queue_list_hdl_find(p_lst_queue, u32_hdl);
    if (p_st_queue)
    {
        if (p_st_session->p_queue)
            frfree(p_st_session->p_queue);

        p_st_session->p_queue = frstrdup(p_st_queue->arr_queue);
        if (p_st_session->p_queue == NULL)
            return FR_FAIL;

        /* 设置title */
        snprintf(arr_title, sizeof(arr_title), "NOTIFY %s", p_st_session->p_queue);
        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;

        /* notify.mq.topic */
        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_NOTIFY_TOPIC, p_st_session->p_queue);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        /* 设置title */
        snprintf(arr_title, sizeof(arr_title), "NOTIFY");
        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }

    /* xml数据需要完整上报，如果i_xml_todo为1并且数据为xml格式，返回todo */
    if (ui_left_len < ui_segmlen - ui_submd_len)
        i_xml_todo = 1;

    i_ret = __ibmmq_msg_data_analysis(p_st_body_data, p_st_private, p_st_data, p_data, ui_report_len
                                    , p_st_private->i_msg_type, arr_report_key, IBMMQ_RESPONSE, i_xml_todo, s_ccsid);
    if (i_ret != FR_SUCC)
        return i_ret;

    snprintf(arr_size, sizeof(arr_size), "notify.%s", MQ_MESSAGE_SIZE);

    // 消息个数上报
    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_size, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    p_st_private->i_pubsub_flag = IBMMQ_MSG_NOTIFY;

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  MESSAGE_DATA解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
            :  p_report_pre(上报前缀)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_message_data_analysis(Frreport_body_data *p_st_body_data
                                        , L7session_ibmmq_private *p_st_private
                                        , Frbyte_Packet *p_st_data
                                        , char *p_report_pre)
{
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    char arr_queue[49];
    char arr_title[64];
    char arr_format[9];
    char *p_data = NULL;
    short s_ccsid = 0;
    uint32_t u32_msg_len = 0;
    unsigned int ui_report_len = 0;
    unsigned int ui_left_len = 0;
    unsigned int ui_submd_len = 0;
    int i_xml_todo = 0;
    int i_offset = 0;
    int i_idx = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    /* 找到MSH */
    i_offset = bytebuff_getPosition(p_st_data);
    if (i_offset == -1)
        return FR_FAIL;
    i_ret = bytebuff_memstr(p_st_data, i_offset, 0, IBMMQ_STRUCTID_MSH, 3, &i_idx);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 消息长度 */
    bytebuff_setPosition(p_st_data, i_idx+8);
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_msg_len, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* XQH */
    i_ret = bytebuff_memstr(p_st_data, i_offset, 0, IBMMQ_STRUCTID_XQH, 4, &i_idx);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_setPosition(p_st_data, i_idx+8);
//    bytebuff_skip(p_st_data, 16);
    memset(arr_queue, 0x00, sizeof(arr_queue));

    /* 队列名 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 48);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_queue);

    /* 跳过Rmt QMgr */
    bytebuff_skip(p_st_data, 4);
    
    /* 添加队列名到session */
    if (p_st_session->p_queue)
        frfree(p_st_session->p_queue);

    p_st_session->p_queue = frstrdup(arr_queue);
    if (p_st_session->p_queue == NULL)
        return FR_FAIL;

    /* request.mq.queue上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQ_QUE, p_st_session->p_queue);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    memset(arr_title, 0x00, sizeof(arr_title));
    /* 设置title */
    snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_session->p_queue);
    if (p_st_session->p_title)
        frfree(p_st_session->p_title);

    p_st_session->p_title = frstrdup(arr_title);
    if (p_st_session->p_title == NULL)
        return FR_FAIL;

    /* mq.method上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD, "PUT");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_left_len = bytebuff_remaining(p_st_data);
    i_ret = bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, IBMMQ_MQMD_STRUCTID, 2, &i_idx);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_setPosition(p_st_data, i_idx);
    ui_left_len -= i_idx;

    memset(arr_format, 0x00, sizeof(arr_format));
    /* MSMD解析 */
    i_ret = __ibmmq_md_analysis(p_st_private, p_st_body_data, p_st_head->u32_byte_order
                              , p_st_data, &ui_left_len, &s_ccsid, IBMMQ_REQUEST, arr_format);
    if (i_ret != FR_SUCC)
        return i_ret;

    /* 结构化数据头部解析 */
    i_ret = __ibmmq_submd_analysis(p_st_private, p_st_body_data, p_st_data
                                 , ui_left_len, p_report_pre, &ui_submd_len, &s_ccsid);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_left_len -= ui_submd_len;

    /* 剩余长度不足消息长度, 剩余长度不足要上报的长度 */
    if (u32_msg_len > bytebuff_remaining(p_st_data)+p_st_head->ui_head_len && bytebuff_remaining(p_st_data) < APM_REPORT_MQ_MAX)
    {
        /* 当前解析的数据包只是消息的一部分，后面还有消息的后半部分 */
        if (p_st_private->p_st_fragment->u64_left_len == 0)
        {
            /* 还需要的消息内容的长度 */
            p_st_private->ui_left_msgfragment_len = u32_msg_len - ui_submd_len - ui_left_len;
            p_st_private->i_msgfragment_flag = 1;
        }
        return APM_L7_ANALYZE_TODO;
    }

    if (ui_left_len != 0)
    {
        /* MQADMIN消息解析 */
        if (strncmp(arr_format, IBMMQ_MQFMT_ADMIN, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_EVENT, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_PCF, 8) == 0)
        {
            i_ret = __ibmmq_data_analysis_admin(p_st_body_data, p_st_data, u32_msg_len, (char *)"PUT", p_st_head->u32_byte_order);
            return i_ret;
        }

        ui_report_len = u32_msg_len > bytebuff_remaining(p_st_data)+p_st_head->ui_head_len ? bytebuff_remaining(p_st_data) : u32_msg_len;

        p_data = (char *)frmalloc(ui_report_len + 1);
        if (p_data == NULL)
            return FR_FAIL;

        /* 取消息数据 */
        memset(p_data, 0x00, ui_report_len + 1);
        i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_report_len);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
    }

    /* xml数据需要完整上报，如果i_xml_todo为1并且数据为xml格式，返回todo */
    if (ui_left_len < u32_msg_len - ui_submd_len)
        i_xml_todo = 1;

    i_ret = __ibmmq_msg_data_analysis(p_st_body_data, p_st_private, p_st_data, p_data, ui_report_len
                                    , p_st_private->i_msg_type, p_report_pre, IBMMQ_REQUEST, i_xml_todo, s_ccsid);
    return i_ret;
}

/*******************************************************************************
*  FUNC     :  MQGET解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_get_analysis(Frreport_body_data *p_st_body_data
                               , L7session_ibmmq_private *p_st_private
                               , Frbyte_Packet *p_st_data)
{
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    Queue_lst_ibmmq *p_lst_queue = NULL;
    Queue_lst_ibmmq *p_st_queue = NULL;
    char arr_title[64];
    uint32_t u32_hdl = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    p_lst_queue = p_st_session->p_lst_queue;
    /* mq.method上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD, "GET");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 12);
    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 用Hdl查找对应的队列名 */
    p_st_queue = ibmmq_queue_list_hdl_find(p_lst_queue, u32_hdl);
    if (p_st_queue)
    {
        if (p_st_session->p_queue)
            frfree(p_st_session->p_queue);

        p_st_session->p_queue = frstrdup(p_st_queue->arr_queue);
        if (p_st_session->p_queue == NULL)
            return FR_FAIL;
    }

    memset(arr_title, 0x00, sizeof(arr_title));
    /* title上报 */
    if (p_st_session->p_queue != NULL)
    {
        snprintf(arr_title, sizeof(arr_title), "GET %s", p_st_session->p_queue);

        /* 保存title到session */
        if (p_st_session->p_title != NULL)
            frfree(p_st_session->p_title);

        p_st_session->p_title = frstrdup(arr_title);
        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }
    else
    {
        if (p_st_session->p_title != NULL)
            frfree(p_st_session->p_title);

        p_st_session->p_title = frstrdup("GET");
        if (p_st_session->p_title == NULL)
            return FR_FAIL;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQGET_REPLY解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  ui_data_len(数据长度)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_getreply_analysis(Frreport_body_data *p_st_body_data
                                    , L7session_ibmmq_private *p_st_private
                                    , Frbyte_Packet *p_st_data
                                    , unsigned int ui_data_len
                                    , char *p_report_pre)
{
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    char arr_format[9];
    char arr_size[64];
    char arr_code[10];
    char *p_data = NULL;
    uint32_t u32_compl_code = 0;
    uint32_t u32_reason_code = 0;
    uint32_t u32_msg_len = 0;
    uint32_t ui_submd_len = 0;
    unsigned int ui_report_len = 0;
    unsigned int ui_left_len = 0;
    short s_ccsid = 0;
    int i_xml_todo = 0;
    int i_offset = 0;
    int i_md_idx = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_private == NULL
        || p_st_private->p_st_l7_session == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;
    if (p_st_head == NULL)
        return FR_FAIL;

    ui_left_len = ui_data_len;
    if (ui_left_len < 16)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, 4);

    /* 取GET结果返回值 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_compl_code, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 取原因码 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_reason_code, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 结果上报 */
    i_ret = frreport_body_l7_add_int(p_st_body_data, IBMMQ_RESP_CODE, u32_reason_code);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    memset(arr_code, 0x00, sizeof(arr_code));
    snprintf(arr_code, sizeof(arr_code), "%d", u32_reason_code);

    /* code_string上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, IBMMQ_RESP_CODE_STRING, arr_code);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (u32_compl_code != 0)
        return FR_SUCC;

    bytebuff_skip(p_st_data, 4);
    ui_left_len -= 16;

    /* 找到MD */
    i_offset = bytebuff_getPosition(p_st_data);
    if (i_offset == -1)
        return FR_FAIL;
    i_ret = bytebuff_memstr(p_st_data, i_offset, 0, IBMMQ_MQMD_STRUCTID, 2, &i_md_idx);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    i_md_idx = i_md_idx - bytebuff_getPosition(p_st_data);
    if ((int)ui_left_len < i_md_idx)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, i_md_idx);
    ui_left_len -= i_md_idx;

    memset(arr_format, 0x00, sizeof(arr_format));
    /* MD解析 */
    i_ret = __ibmmq_md_analysis(p_st_private, p_st_body_data, p_st_head->u32_byte_order
                              , p_st_data, &ui_left_len, &s_ccsid, IBMMQ_RESPONSE, arr_format);
    if (i_ret != FR_SUCC)
        return i_ret;

    /* GMO解析 */
    i_ret = __ibmmq_gmo_analysis(p_st_body_data, p_st_data, p_st_session, &ui_left_len, p_st_head->u32_byte_order);
    if (i_ret != FR_SUCC)
        return i_ret;

    if (ui_left_len < 4)
        return APM_L7_ANALYZE_TODO;

    /* 取消息长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_msg_len, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    ui_left_len -= 4;

    /* 结构化数据头部解析 */
    i_ret = __ibmmq_submd_analysis(p_st_private, p_st_body_data, p_st_data
                                 , ui_left_len, p_report_pre, &ui_submd_len, &s_ccsid);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    ui_left_len -= ui_submd_len;

    /* 剩余长度不足消息长度, 剩余长度不足要上报的长度 */
    if (ui_left_len < u32_msg_len - ui_submd_len && ui_left_len < APM_REPORT_MQ_MAX)
    {
        /* 当前解析的数据包只是消息的一部分，后面还有消息的后半部分 */
        if (p_st_private->p_st_fragment->u64_left_len == 0)
        {
            /* 还需要的消息内容的长度 */
            p_st_private->ui_left_msgfragment_len = u32_msg_len - ui_submd_len - ui_left_len;
            p_st_private->i_msgfragment_flag = 1;
        }
        return APM_L7_ANALYZE_TODO;
    }

    /* 有数据 */
    if (ui_left_len != 0)
    {
        /* MQADMIN消息解析 */
        if (strncmp(arr_format, IBMMQ_MQFMT_ADMIN, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_EVENT, 8) == 0
            || strncmp(arr_format, IBMMQ_MQFMT_PCF, 8) == 0)
        {
            i_ret = __ibmmq_data_analysis_admin(p_st_body_data, p_st_data, u32_msg_len, (char *)"GET", p_st_head->u32_byte_order);
            return i_ret;
        }

        ui_report_len = ui_left_len < u32_msg_len ? ui_left_len : u32_msg_len;

        p_data = (char *)frmalloc(ui_report_len + 1);
        if (p_data == NULL)
            return FR_FAIL;
        memset(p_data, 0x00, ui_report_len + 1);

        i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_report_len);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
    }

    /* xml数据需要完整上报，如果i_xml_todo为1并且数据为xml格式，返回todo */
    if (ui_left_len < u32_msg_len - ui_submd_len)
        i_xml_todo = 1;

    i_ret = __ibmmq_msg_data_analysis(p_st_body_data, p_st_private, p_st_data, p_data, ui_report_len
                                    , p_st_private->i_msg_type, p_report_pre, IBMMQ_RESPONSE, i_xml_todo, s_ccsid);
    if (i_ret != FR_SUCC)
        return i_ret;

    snprintf(arr_size, sizeof(arr_size), "response.%s", MQ_MESSAGE_SIZE);
    // 消息个数上报
    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_size, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQCLOSE解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_close_analysis(L7session_ibmmq_private *p_st_private
                                                        , Frbyte_Packet *p_st_data)
{
    L7_head_ibmmq *p_st_head = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    uint32_t u32_hdl = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_l7_session == NULL
        || p_st_private->p_st_head == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;
    p_st_head = p_st_private->p_st_head;

    bytebuff_skip(p_st_data, 12);
    /* Hdl */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_hdl, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (p_st_session->p_lst_queue == NULL)
        return FR_FAIL;

    i_ret = ibmmq_queue_list_hdl_del(&p_st_session->p_lst_queue, u32_hdl);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQCONN_REPLY解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  p_i_login(login成功否)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_connreply_analysis(L7session_ibmmq_private *p_st_private
                                                        , Frbyte_Packet *p_st_data
                                                        , int *p_i_login)
{
    L7_head_ibmmq *p_st_head = NULL;
    uint32_t u32_compl_code = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_head == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_head = p_st_private->p_st_head;

    bytebuff_skip(p_st_data, 4);
    /* compl code */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_compl_code, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    *p_i_login = u32_compl_code;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  MQCONN_REPLY解析
*  ARGS     :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  p_st_data(数据)
            :  p_i_disc(login成功否)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int ibmmq_discreply_analysis(L7session_ibmmq_private *p_st_private
                                                        , Frbyte_Packet *p_st_data
                                                        , int *p_i_disc)
{
    L7_head_ibmmq *p_st_head = NULL;
    uint32_t u32_compl_code = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_head == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_head = p_st_private->p_st_head;

    bytebuff_skip(p_st_data, 4);
    /* compl code */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_compl_code, (LITTLE_BIG_ENDIAN)p_st_head->u32_byte_order);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    *p_i_disc = u32_compl_code;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析头部数据
*  ARGS     :  p_data(IBM MQ数据包数据)
            :  ui_head_len(头部数据长度)
            :  pp_st_head(出力头部信息)
*  RTN      :  int
*  NOTE     :
*******************************************************************************/
int ibmmq_analysis_head(char *p_data
                      , unsigned int ui_head_len
                      , L7_head_ibmmq **pp_st_head)
{
    unsigned char *p_data_tmp = NULL;
    char arr_len[5];
    char arr_ccsid[3];
    uint32_t *p_u32_len = 0;
    uint16_t *p_u16_ccsid = 0;
    uint32_t u32_byte_order = 0;
    uint32_t u32_segm_type = 0;
    unsigned int ui_offset = 0;
    unsigned int ui_data_len = 0;
    short s_ccsid = 0;
    L7_head_ibmmq *p_st_head = NULL;

    if (p_data == NULL || pp_st_head == NULL
        || (ui_head_len != IBMMQ_HEAD_LEN_TSHM && ui_head_len != IBMMQ_HEAD_LEN_TSH))
        return FR_FAIL;

    memset(arr_len, 0x00, sizeof(arr_len));
    memset(arr_ccsid, 0x00, sizeof(arr_ccsid));

    p_data_tmp = (unsigned char *)p_data;
    /* 头部StructID, 4字节 */
    if (memcmp(p_data_tmp, IBMMQ_STR_TSH, 3) != 0)
        return FR_FAIL;
    p_data_tmp += 4;
    ui_offset += 4;

    /* 数据长度解析, 4字节 */
    memcpy(arr_len, p_data_tmp, 4);
    p_u32_len = (uint32_t *)arr_len;
    ui_data_len = ntohl(*p_u32_len);
    /* 消息的最大长度100M */
    if (ui_data_len > IBMMQ_LEN_M*100 || ui_data_len < ui_head_len)
        return FR_FAIL;

    p_data_tmp += 4;
    ui_offset += 4;

    /* StructID为 TSHM类型的数据, 过掉8字节*/
    if (ui_head_len == IBMMQ_HEAD_LEN_TSHM)
    {
        p_data_tmp += 8;
        ui_offset += 8;
    }

    /* 数据读取方式（大小头）,1字节 */
    u32_byte_order = *p_data_tmp;
    if (u32_byte_order != 1 && u32_byte_order != 2)
        return FR_FAIL;
    p_data_tmp += 1;
    ui_offset += 1;

    /* 消息类型, 1字节 */
    u32_segm_type = *p_data_tmp;
    p_data_tmp += 1;
    ui_offset += 1;

    /* CCSID */
    p_data_tmp += 14;
    ui_offset += 14;
    memcpy(arr_ccsid, p_data_tmp, 2);
    p_u16_ccsid = (uint16_t *)arr_ccsid;
    if (u32_byte_order == 1)
        s_ccsid = be16toh((uint16_t )*p_u16_ccsid);
    else
        s_ccsid = le16toh((uint16_t )*p_u16_ccsid);

    p_st_head = (L7_head_ibmmq *)frmalloc(sizeof(L7_head_ibmmq));
    if (p_st_head == NULL)
        return FR_FAIL;
    memset(p_st_head, 0x00, sizeof(L7_head_ibmmq));

    /* StructID */
    if (ui_head_len == IBMMQ_HEAD_LEN_TSHM)
        memcpy(p_st_head->arr_structid, p_data, IBMMQ_TSHx_LEN);
    else
        memcpy(p_st_head->arr_structid, p_data, IBMMQ_TSH_LEN);

    /* Message长度 */
    p_st_head->ui_msg_len = ui_data_len;

    /* Byte Order */
    p_st_head->u32_byte_order = u32_byte_order;

    /* 请求类型 */
    p_st_head->u32_segm_type = u32_segm_type;

    /* 头数据长度 */
    p_st_head->ui_head_len = ui_head_len;

    /* CCSID */
    p_st_head->s_ccsid = s_ccsid;

    *pp_st_head = p_st_head;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  IBM MQ的体部解析
*  ARGS     :  p_st_data(数据)
            :  p_st_body_data(上报链表)
            :  p_st_private(IBM MQ私有数据)
            :  i_req_resp(request/response)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
int ibmmq_analysis_body(Conntrack *p_st_conn
                      , Apm_packet *p_st_packet
                      , Frbyte_Packet *p_st_data
                      , Frreport_body_data *p_st_body_data
                      , L7session_ibmmq_private *p_st_private
                      , int i_req_resp)
{
    L7_head_ibmmq *p_st_head_info = NULL;
    L7Session_ibmmq *p_st_session = NULL;
    Frreport_data *p_st_report_data=NULL;
    unsigned int ui_head_len = 0;
    unsigned int ui_data_len = 0;
    char arr_type[10];
    char arr_info[64];
    int i_login = 0;
    int i_disc = 0;
    int i_ret = 0;

    if (p_st_data == NULL || p_st_body_data == NULL
        || p_st_private == NULL || p_st_private->p_st_l7_session == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_l7_session;

    p_st_head_info = p_st_private->p_st_head;
    if (p_st_head_info == NULL)
        return FR_FAIL;

    ui_head_len = p_st_head_info->ui_head_len;

    /* 取得数据包长度 */
    ui_data_len = bytebuff_remaining(p_st_data);

    memset(arr_type, 0x00, sizeof(arr_type));
    if (i_req_resp == IBMMQ_REQUEST)
    {
        strcpy(arr_type, APM_REPORT_KEY_REQ);
        strcat(arr_type, ".");
    }
    else
    {
        strcpy(arr_type, APM_REPORT_KEY_RESP);
        strcat(arr_type, ".");
    }

    if (p_st_session->p_server == NULL)
    {
        p_st_session->p_server = frstrdup("IBMMQ");
        if (p_st_session->p_server == NULL)
            return FR_FAIL;
    }

    switch(p_st_head_info->u32_segm_type)
    {
        case IBMMQ_INITIAL:
            i_ret = ibmmq_initial_analysis(p_st_body_data, p_st_private, p_st_data,  ui_data_len, arr_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
//            p_st_private->i_status_flag = FRLOGIN_SUCC;
            break;
        case IBMMQ_USERID:
            i_ret = ibmmq_userid_analysis(p_st_body_data, p_st_private, p_st_data,  ui_data_len, arr_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            p_st_private->i_status_flag = FRLOGIN_START;
            break;
        case IBMMQ_MQPUT:
        case IBMMQ_MQPUT1:
            i_ret = ibmmq_put_analysis(p_st_body_data, p_st_private, p_st_data,  ui_data_len, arr_type, p_st_head_info->u32_segm_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MQPUT_REPLY:
        case IBMMQ_MQPUT1_REPLY:
            i_ret = ibmmq_putreply_analysis(p_st_body_data, p_st_private, p_st_data,  ui_data_len);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_ASYNC_MESSAGE:
            i_ret = ibmmq_async_msg_analysis(p_st_body_data, p_st_private, p_st_data, ui_data_len, arr_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_SPI:
            i_ret = ibmmq_spi_analysis(p_st_private, p_st_data, ui_data_len, arr_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_SPI_REPLY:
            i_ret = ibmmq_spireply_analysis(p_st_private, p_st_data, ui_data_len, arr_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MQSUB:
            i_ret = ibmmq_sub_analysis(p_st_body_data, p_st_private, p_st_data, ui_data_len);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_REQUEST_MSGS:
//            i_ret = ibmmq_requestmsg_analysis(p_st_body_data, p_st_data, p_st_private);
//            if (i_ret == FR_FAIL)
//                return FR_FAIL;
            break;
        case IBMMQ_MQOPEN:
            i_ret = ibmmq_open_analysis(p_st_private, p_st_data, ui_data_len);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MQOPEN_REPLY:
            i_ret = ibmmq_openreply_analysis(p_st_private, p_st_data, ui_data_len);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MESSAGE:
            i_ret = ibmmq_message_data_analysis(p_st_body_data, p_st_private, p_st_data, arr_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MQGET:
            i_ret = ibmmq_get_analysis(p_st_body_data, p_st_private, p_st_data);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MQGET_REPLY:
            i_ret = ibmmq_getreply_analysis(p_st_body_data, p_st_private, p_st_data, ui_data_len, arr_type);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MQCLOSE:
            i_ret = ibmmq_close_analysis(p_st_private, p_st_data);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case IBMMQ_MQCONN_REPLY:
            i_ret = ibmmq_connreply_analysis(p_st_private, p_st_data, &i_login);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            if (i_login == 0)
            {
                if (p_st_session->p_username != NULL && *p_st_session->p_username != '\0')
                    snprintf(arr_info, sizeof(arr_info), "%s login", p_st_session->p_username);
                else
                    snprintf(arr_info, sizeof(arr_info), "login");

                p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON, arr_info, &p_st_packet->st_timestamp);
                p_st_private->i_status_flag = FRLOGIN_SUCC;
            }
            else
            {
                if (p_st_session->p_username != NULL && *p_st_session->p_username != '\0')
                    snprintf(arr_info, sizeof(arr_info), "%s login reject", p_st_session->p_username);
                else
                    snprintf(arr_info, sizeof(arr_info), "login reject");

                p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGON_REJECT, arr_info, &p_st_packet->st_timestamp);
            }
            if (p_st_report_data)
            {
                i_ret = frreport_send(g_p_apm_context, &p_st_report_data);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
            }
            break;
        case IBMMQ_MQDISC_REPLY:
            i_ret = ibmmq_discreply_analysis(p_st_private, p_st_data, &i_disc);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            if (i_disc == 0)
            {
                if (p_st_session->p_username != NULL && *p_st_session->p_username != '\0')
                    snprintf(arr_info, sizeof(arr_info), "%s logout", p_st_session->p_username);
                else
                    snprintf(arr_info, sizeof(arr_info), "logout");

                p_st_report_data = frreport_update_create(p_st_conn, APM_REPORT_UPDATE_LOGOUT, arr_info, &p_st_packet->st_timestamp);
                if (p_st_report_data)
                {
                    i_ret = frreport_send(g_p_apm_context, &p_st_report_data);
                    if (i_ret == FR_FAIL)
                        return FR_FAIL;
                }
                p_st_private->i_status_flag = FRLOGOUT_END;
            }
            break;
        case IBMMQ_MQCONN:
        case IBMMQ_RESYNC:
        case IBMMQ_RESET:
        case IBMMQ_STATUS:
        case IBMMQ_SECURITY:
        case IBMMQ_PING:
        case IBMMQ_HEARTBEAT:
        case IBMMQ_CONAUTH_INFO:
        case IBMMQ_RENEGOTIATE_DATA:
        case IBMMQ_SOCKET_ACTION:
        case IBMMQ_NOTIFICATION:
        case IBMMQ_MQDISC:
        case IBMMQ_MQSET:
        case IBMMQ_MQINQ:
        case IBMMQ_MQCMIT:
        case IBMMQ_MQBACK:
        case IBMMQ_MQSTAT:
        case IBMMQ_MQSUBRQ:
        case IBMMQ_MQCLOSE_REPLY:
        case IBMMQ_MQSET_REPLY:
        case IBMMQ_MQINQ_REPLY:
        case IBMMQ_MQCMIT_REPLY:
        case IBMMQ_MQBACK_REPLY:
        case IBMMQ_MQSUB_REPLY:

        case IBMMQ_MQSTAT_REPLY:
        case IBMMQ_MQSUBRQ_REPLY:
            break;
        default:
            return FR_SUCC;
    }

    return i_ret;
}
